/**
 * 
 */
package br.edu.ufcg.embedded.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jgrapht.Graph;
import org.jgrapht.generate.ScaleFreeGraphGenerator;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleDirectedGraph;
import org.jgrapht.graph.SimpleWeightedGraph;

import br.edu.ufcg.embedded.mysocial.GraphCacheManager;
import br.edu.ufcg.embedded.mysocial.UserGenerator;
import br.edu.ufcg.embedded.mysocial.VertexGenerator;
import br.embedded.socialapp.business.Usuario;
import br.embedded.socialapp.data.FriendshipDAO;

/**
 * @author Daniel
 *
 */
public class StatisticsGenerator {

	private static int MAX_ITERATIONS = 1;
	private static int NUMBER_OF_VERTICES = 10000;
	private static int NUMBERT_OF_THREADS = 10;
	private static int MAX_RECORDS = 1000;
	private static int VERTEX_DEGREE = 400;
	private static int MAX_LEVELS = 2;
	private static Topology TOPOLOGY = Topology.ScaleFree;
	private static final String STATISTICS_PATH = "statistics.txt";
	private static final String BULK_PATH = "/home/daniel/IDE/tmp/eclipse/workspace/SocialNetsAppClientRMI/bulk/";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception
	{
		if (args != null && args.length == 7)
		{
			MAX_ITERATIONS = Integer.parseInt(args[0]);
			NUMBER_OF_VERTICES = Integer.parseInt(args[1]);
			VERTEX_DEGREE = Integer.parseInt(args[2]);
			MAX_LEVELS = Integer.parseInt(args[3]);
			
			if (Topology.ScaleFree.toString().equalsIgnoreCase(args[4]))
				TOPOLOGY = Topology.ScaleFree;
			else if (Topology.EvenDegree.toString().equalsIgnoreCase(args[4]))
				TOPOLOGY = Topology.EvenDegree;
			else if (Topology.ScaleFree_Facebook.toString().equalsIgnoreCase(args[4]))
				TOPOLOGY = Topology.ScaleFree_Facebook;
			else
				throw new Exception("Erro");
			
			NUMBERT_OF_THREADS = Integer.parseInt(args[5]);
			MAX_RECORDS = Integer.parseInt(args[6]);
		}
		collectStatistics();
	}
	
	private static void collectStatistics()
	{
		FriendshipDAO.getInstance().truncate();
		
		double edgesAverage = 0.0;
		double durationAverage = 0.0;
		
		for (int i = 0; i < MAX_ITERATIONS; i++)
		{
			Long t1 = System.currentTimeMillis();
			
			Graph<String, DefaultEdge> graph = createGraph();
						
			Long t2 = System.currentTimeMillis();
			System.out.println("Montar Grafo: " + (t2 - t1)/1000);

			Long t3 = System.currentTimeMillis();
			GraphCacheManager graphCacheManager = new GraphCacheManager(graph, new ArrayList<String>(graph.vertexSet()),
					MAX_LEVELS, NUMBERT_OF_THREADS, MAX_RECORDS, BULK_PATH);
			graphCacheManager.run();
			
			Long t4 = System.currentTimeMillis();
			
            edgesAverage += graph.edgeSet().size();
            durationAverage += (t4 - t3);
            
			writeStatistics(graph.edgeSet().size(), (t4 - t3));
			
			graphCacheManager = null;
			graph = null;
			
			//Runtime r = Runtime.getRuntime();
			//r.runFinalization();
			//r.gc();
		}
		
		//writeStatisticsAverage(edgesAverage, durationAverage);
	}
	
	private static Graph<String, DefaultEdge> createGraph()
	{
		Graph<String, DefaultEdge> graph = null;
		
		if (TOPOLOGY == Topology.ScaleFree)
		{
			//graph = new SimpleWeightedGraph<String, DefaultEdge>(DefaultEdge.class);
			graph = new SimpleDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
			ScaleFreeGraphGenerator<String, DefaultEdge> generator = new ScaleFreeGraphGenerator<String, DefaultEdge>(NUMBER_OF_VERTICES, 100);
			generator.generateGraph(graph, new VertexGenerator(), null);
		}
		else if (TOPOLOGY == Topology.ScaleFree_Facebook) {
			graph = FriendshipDAO.getInstance().getSocialConnections().getGraph();
		}
		else {
			List<String> usersList = UserGenerator.generateUsers(NUMBER_OF_VERTICES);
			graph = UserGenerator.buildFriendshipGraph(usersList, VERTEX_DEGREE);
		}
		return graph;
	}
	
	private static void writeStatistics(int edgeSize, long duration)
	{
		try {
			FileManager fileManager = new FileManager();
			fileManager.openOrCreateFile(STATISTICS_PATH);
			fileManager.write(getLine(edgeSize, duration));
			fileManager.close();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
	
/*	private static void writeStatisticsAverage(double edgesAverage, double durationAverage)
	{
		try {
			FileManager fileManager = new FileManager();
			fileManager.openOrCreateFile(STATISTICS_PATH);
			fileManager.write(getLine((edgesAverage / MAX_ITERATIONS), (durationAverage / MAX_ITERATIONS)));
			fileManager.close();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}*/
	
	private static String getLine(int edgeSize, long duration)
	{
		StringBuilder sb = new StringBuilder();
		
		sb.append(NUMBER_OF_VERTICES);
		sb.append(";");
		sb.append(edgeSize);
		sb.append(";");
		sb.append(TOPOLOGY);
		sb.append(";");
		sb.append(MAX_LEVELS);
		sb.append(";");
		sb.append(NUMBERT_OF_THREADS);
		sb.append(";");
		sb.append(duration);
		
		return sb.toString();
	}
	
/*	private static String getLine(double edgeAverage, double durationAverage)
	{
		StringBuilder sb = new StringBuilder();
		
		sb.append(NUMBER_OF_VERTICES);
		sb.append(";");
		sb.append(edgeAverage);
		sb.append(";");
		sb.append(TOPOLOGY);
		sb.append(";");
		sb.append(MAX_LEVELS);
		sb.append(";");
		sb.append(durationAverage);
		
		return sb.toString();
	}*/
}